package org.tea.inventory.db.util;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.tea.inventory.db.domain.AlumniVisitor;
import org.tea.inventory.db.util.wx.entity.AccessVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 腾讯优图API工具类
 *
 *  请求说明：
 * 登录之后授权的生命期为 30 分钟，若在生命期内持续调用接口，生命期会重
 * 置回 30 分钟，只有最后一次调用接口 30 分钟内无接口调用，授权才会失效。
 *
 * 后续所有请求都必须在请求头(Request Headers)中带上 result 中的除 Access
 * 的三个参数，
 * 例如：
 * curl 'http://IP:PORT/youtu/api/libs/query_hierarchy' \
 * -H 'content-type: application/json' \
 * -H 'user-name: admin' \
 * -H 'facein-csrf: dfb55561362bd555ed0d8e5825bd874e' \
 * -H 'session-id:
 * 6c128b81c092a08dc07c743b72c18f24|b26cc80b9b41f72d5fb7ef9279889583d66da7f14e873166f302e
 * d9f558904bf' \
 * --data '{"org_id":2,"tracing_id":"third-20181207172043293-1818"}'
 *
 */
public class VisitorUtil {
    private static Logger log = LoggerFactory.getLogger(VisitorUtil.class);
    //创建静态map缓存
    private static Map<String, AccessVisitor> youtuCacheToken = new HashMap<String, AccessVisitor>();

    public static String USERNAME = "admin";

    public static String PASSWORD = "1qaz2wsxpassword";

    public static Integer STARTE_DEFAULT = 0;//默认状态
    public static Integer STARTE_DELETED = 1;//删除
    public static Integer STARTE_INVITE = 2;//邀请状态，访客未填写信息
    public static Integer STARTE_SUBMIT = 3;//信息已添加到人员管理
    public static Integer STARTE_FINISH = 4;//信息已添加到权限组

    //权限组的ID，可通过前端控制台查询得到
    private static Integer LIB_ID = 2;
    //所属组织架构id，可通过门禁Web控制台查询得到，可重复多个
    private static String ORG_ID = "6";

    //优图后端访问地址（IP+PORT/域名）
    private static  String URL = "http://faces.dgtis.com";
    //验证调用方是否拥有调用二次开发接口的权限 POST接口
    private static String VERIFY_ACCESS_AUTHORITY = URL + "/youtu/api/user/login";

    //注册人员接口 POST接口
    private static String REGISTER_USER = URL + "/youtu/api/persons/add";

    //编辑人员接口 POST接口
    private static String UPDATE_USER = URL + "/youtu/api/persons/update";

    //删除人员接口 POST接口
    private static String DEL_USER = URL + "/youtu/api/persons/delete";

    //查询人员接口 POST接口
    private static String QUERY_USER = URL + "/youtu/api/persons/query_hierarchy";

    //增加权限组人员接口
    private static String ADD_PERSON = URL + "/youtu/api/libs/add_person";


    /**
     * 上传信息到人脸识别系统
     * @param visitor 人脸信息
     * @param filepath 图片路径
     * @return
     */
    public static AlumniVisitor upload(AlumniVisitor visitor, String filepath){
         String extract_result = "-1";
        //1.权限验证
        AccessVisitor accessVisitor = VisitorUtil.verifyPermissions();
        if(accessVisitor != null){
            //2.上传到人员管理
            Map<String, String> textMap = new HashMap<String, String>();
            textMap.put("origin_id", visitor.getOriginId());
            textMap.put("name", visitor.getVisitorName());
            textMap.put("gender", visitor.getVisitorGender());
            textMap.put("org_id", ORG_ID);
            //设置file的name，路径
            Map<String, String> fileMap = new HashMap<String, String>();
            fileMap.put("photo_path",filepath);
            fileMap.put("photo_path_view",filepath);
            String contentType = "jpg";

            Map<String, String> map = VisitorUtil.addOrUpdatePersons(textMap, fileMap, contentType,"add");
            extract_result = map.get("extract_result");
            if("0".equals(extract_result)){
                String person_id = map.get("person_id");
                visitor.setPersonId(person_id);
            } else {
                System.out.println("添加到人员管理 失败");
            }
        } else {
            System.out.println("验证调用方权限失败，AccessVisitor为空");
        }
        visitor.setExtractResult(extract_result);
        return visitor;
    }

    /**
     * 更新用户信息
     * @param visitor
     * @param filepath
     * @return
     */
    public static AlumniVisitor update(AlumniVisitor visitor, String filepath){
        String extract_result = "-1";
        //1.权限验证
        AccessVisitor accessVisitor = VisitorUtil.verifyPermissions();
        if(accessVisitor != null){
            //封装请求体
            Map<String, String> textMap = new HashMap<String, String>();
            textMap.put("id", visitor.getPersonId());
            textMap.put("origin_id", visitor.getOriginId());
            textMap.put("name", visitor.getVisitorName());
            textMap.put("gender", visitor.getVisitorGender());
            textMap.put("org_id", ORG_ID);
            Map<String, String> fileMap = new HashMap<String, String>();
            fileMap.put("photo_path",filepath);
            fileMap.put("photo_path_view",filepath);
            String contentType = "jpg";
            //2.更新人员信息
            Map<String, String> map = VisitorUtil.addOrUpdatePersons(textMap, fileMap, contentType,"update");
            extract_result = map.get("extract_result");
            if("0".equals(map.get("extract_result"))){
                String person_id = map.get("person_id");
                visitor.setPersonId(person_id);
            } else {
                System.out.println("修改到人员管理 失败");
            }
        } else {
            System.out.println("验证调用方权限失败，AccessVisitor为空");
        }
        visitor.setExtractResult(extract_result);
        return visitor;
    }


    /**
     * 人员添加到权限组管理
     * @param person_id 人员组中的人员ID
     *  lib_id 目标权限组的ID，可通过前端控制台查询得到
     * @return
     */
    public static boolean addPermissionGroup(String person_id){
        JSONObject obj1 = new JSONObject();
        obj1.put("person_id", person_id);
        obj1.put("lib_id", LIB_ID);
        return VisitorUtil.addPerson(obj1);
    }



    /**
     * 权限验证接口，验证调用方是否拥有调用二次开发接口的权限
     */
    private static AccessVisitor verifyPermissions(){
        JSONObject data = new JSONObject();
        data.put("username", VisitorUtil.USERNAME);
        data.put("password", MD5Util.string2MD5(VisitorUtil.PASSWORD).toUpperCase());

        AccessVisitor accessVisitor = youtuCacheToken.get("youtuCacheToken");
        if(accessVisitor != null) {
            long time = accessVisitor.getTime();
            int expiresIn = accessVisitor.getExpiresIn();
            long millions = new Long(expiresIn).longValue() * 1000;
            long newDate = new Date().getTime();
            //获取当前时间跟存入时间的差值
            long rt = newDate - time;
            //判断时间是否已经过期  如果过期(大于)则重新请求， 否则不做处理
            if(rt > millions) {
                accessVisitor = sendRequestAUTHORITY(data);
            }
        } else {
            accessVisitor = sendRequestAUTHORITY(data);
        }
        return accessVisitor;
    }


    private static AccessVisitor sendRequestAUTHORITY(JSONObject object){
        AccessVisitor accessVisitor = null;
        System.out.println("发送请求 验证调用方是否拥有调用二次开发接口的权限");
        JSONObject jsonObject = HttpRequest.httpRequestJson(VERIFY_ACCESS_AUTHORITY, "POST", object.toString(), null);
        System.out.println("result 》》》》》 ： "+jsonObject.toString());

        if (null != jsonObject) {
            try {
                if(jsonObject.containsKey("error_code") && jsonObject.containsKey("error_msg")){
                    String errorCode = jsonObject.getString("error_code");
                    String errorMsg = jsonObject.getString("error_msg");
                    if("0".equals(errorCode) && "Success".equals(errorMsg)){
                        JSONObject json = jsonObject.getJSONObject("result");
                        if(json.containsKey("Access") && json.containsKey("User-Name")
                                && json.containsKey("Facein-Csrf") && json.containsKey("Session-Id")){
                            youtuCacheToken.remove("youtuCacheToken");
                            accessVisitor = new AccessVisitor();
                            accessVisitor.setAccess(json.getInt("Access"));
                            accessVisitor.setUserName(json.getString("User-Name"));
                            accessVisitor.setFaceinCsrf(json.getString("Facein-Csrf"));
                            accessVisitor.setSessionId(json.getString("Session-Id"));
                            accessVisitor.setExpiresIn(1800);
                            accessVisitor.setTime(new Date().getTime());
                            youtuCacheToken.put("youtuCacheToken",accessVisitor);
                        } else
                            accessVisitor = null;
                    } else
                        accessVisitor = null;
                } else
                    accessVisitor = null;
            } catch (JSONException e) {
                accessVisitor = null;
                // 验证调用方是否拥有调用二次开发接口的权限 请求失败
                log.error("验证调用方是否拥有调用二次开发接口的权限 请求失败");
            }
        }
        return accessVisitor;
    }


    /**
     * 添加/更新人员接口
     * @param textMap
     * @param fileMap
     * @param fileType
     * @return
     */
    public static Map<String, String> addOrUpdatePersons(Map<String, String> textMap,
                                                 Map<String, String> fileMap,
                                                 String fileType,
                                                 String type){
        AccessVisitor visitor = verifyPermissions();
        Map<String, String> map = new HashMap<String, String>();
        map.put("extract_result", "-1");
        try {
            JSONObject jsonObject = null;
            if("add".equals(type)){
                System.out.println("发送请求 注册人员接口");
                jsonObject = HttpRequest.formUpload(REGISTER_USER, textMap, fileMap ,fileType, visitor);
                System.out.println("result 》》》》》 ： "+jsonObject.toString());
            } else if("update".equals(type)){
                System.out.println("发送请求 更新人员接口");
                jsonObject = HttpRequest.formUpload(UPDATE_USER, textMap, fileMap ,fileType, visitor);
                System.out.println("result 》》》》》 ： "+jsonObject.toString());
            }
            if (null != jsonObject) {
                if(jsonObject.containsKey("error_code") && jsonObject.containsKey("error_msg")){
                    String errorCode = jsonObject.getString("error_code");
                    String errorMsg = jsonObject.getString("error_msg");
                    if("0".equals(errorCode) && "Success".equals(errorMsg)){
                        JSONObject json = jsonObject.getJSONObject("result");
                        //person_id : 注册成功的人员 ID，如果 extract_result 不是0，则没有意义
                        if(json.containsKey("person_id") && json.containsKey("extract_result")){
                            String person_id = json.getString("person_id");
                            int extract_result = json.getInt("extract_result");
                            map.put("person_id", person_id);
                            map.put("extract_result",extract_result+"");
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.put("extract_result", "-1");
            log.error("注册人员接口 请求失败");
        }
        return map;
    }


    /**
     * 增加权限组人员接口，（人员下发到设备）
     * @param object
     */
    public static boolean addPerson(JSONObject object){
        AccessVisitor visitor = verifyPermissions();
        Map<String, Object> map = new HashMap<String, Object>();
        boolean flag = false;
        try {
            System.out.println("发送请求 新增权限组人员接口");
            JSONObject jsonObject = HttpRequest.httpRequestJson(ADD_PERSON, "POST", object.toString(), visitor);
            System.out.println("result 》》》》》 ： "+jsonObject.toString());
            if (null != jsonObject) {
                if(jsonObject.containsKey("error_code") && jsonObject.containsKey("error_msg")){
                    String errorCode = jsonObject.getString("error_code");
                    String errorMsg = jsonObject.getString("error_msg");
                    if("0".equals(errorCode) && "Success".equals(errorMsg)){
                        flag = true;
                    }
                }
            }
        } catch (Exception e) {
            map.put("state",-1);
            map.put("massage","出现异常了");
            // 验证调用方是否拥有调用二次开发接口的权限 请求失败
            log.error("增加权限组人员接口 请求失败");
        }
        return flag;
    }

}
